package com.fwtai.service.web;

import com.alibaba.fastjson2.JSONObject;
import com.fwtai.bean.PageFormData;
import com.fwtai.bean.UploadFile;
import com.fwtai.bean.UploadObject;
import com.fwtai.service.AsyncService;
import com.fwtai.tool.IdBuilder;
import com.fwtai.tool.ToolClient;
import com.fwtai.tool.ToolString;
import com.fwtai.web.GoodsDao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 总公司商品业务层
 * @作者 田应平
 * @版本 v1.0
 * @QQ号码 444141300
 * @创建日期 2023-04-07 11:08:26
 * @官网 <url>http://www.fwtai.com</url>
*/
@Service
public class GoodsService{

  @Value("${upload_dir_window}")
  private String dir_window;

  @Value("${upload_dir_linux}")
  private String dir_linux;

  private final AsyncService asyncService;

  private final GoodsDao goodsDao;

  private final ThreadPoolTaskExecutor taskExecutor;

  public GoodsService(final GoodsDao goodsDao,final ThreadPoolTaskExecutor taskExecutor,final AsyncService asyncService){
    this.goodsDao = goodsDao;
    this.taskExecutor = taskExecutor;
    this.asyncService = asyncService;
  }

  public String add(final HttpServletRequest request){
    return CompletableFuture.supplyAsync(()->{
      final PageFormData formData = new PageFormData(request);
      final String p_contract_name = "contract_name";
      final String p_contract_type = "contract_type";
      final String p_thumbnail = "thumbnail";
      final String p_details = "details";
      final String p_price = "price";
      final String p_coupon = "coupon";
      final String validate = ToolClient.validateField(formData,p_contract_name,p_contract_type,p_coupon,p_details,p_price);
      if(validate != null) return validate;
      final String len_contract_name = formData.getString(p_contract_name);
      if(len_contract_name != null && len_contract_name.length() > 64){
        return ToolClient.createJsonFail("商品名称字数太多");
      }
      final String len_contract_type = formData.getString(p_contract_type);
      if(len_contract_type != null && len_contract_type.length() > 19){
        return ToolClient.createJsonFail("商品类型字数太多");
      }
      final String len_details = formData.getString(p_details);
      if(len_details != null && len_details.length() > 921600000){
        return ToolClient.createJsonFail("商品描述字数太多");
      }
      final String len_price = formData.getString(p_price);
      if(len_price != null && len_price.length() > 12){
        return ToolClient.createJsonFail("商品价格字数太多");
      }
      final Long v_contract_type = formData.getLong(p_contract_type);
      if(v_contract_type == null){
        return ToolClient.createJsonFail("商品类型不是有效的数据格式");
      }else{
        formData.put(p_contract_type,v_contract_type);
      }
      final Integer couponValue = formData.getInteger(p_coupon);
      if(couponValue == null){
        return ToolClient.createJsonFail("优惠券数量数据格式有误");
      }
      if(couponValue < 0){
        return ToolClient.createJsonFail("优惠券数量不能小于0");
      }
      formData.put(p_coupon,couponValue);
      final BigDecimal v_price = formData.getBigDecimal(p_price);
      if(v_price == null){
        return ToolClient.createJsonFail("商品价格不是有效的数字");
      }else{
        formData.put(p_price,v_price);
      }
      final String baseDir = ToolString.isLinuxOS() ? dir_linux : dir_window;
      final UploadObject uploadObject = ToolClient.uploadFile(request,baseDir,"/goods",false,1,3,new String[]{p_thumbnail},".jpg",".jpeg",".svg",".png");
      final String errorMsg = uploadObject.getErrorMsg();
      if(errorMsg != null) return ToolClient.createJsonFail(errorMsg);
      final ArrayList<UploadFile> listFiles = uploadObject.getListFiles();
      formData.remove(p_thumbnail);
      listFiles.forEach(uploadFile -> {
        final JSONObject json = new JSONObject(2);
        json.put("fullPath",uploadFile.getFullPath());
        json.put("urlFile",uploadFile.getUrlFile());
        formData.put(p_thumbnail,json.toJSONString());
      });
      formData.put("kid",new IdBuilder().getId121L());//todo 视情况是否需要处理主键重复的而需要删除所上传的文件,如以用户主键创建的表,可使用唯一键约束并结合IGNORE使用
      return ToolClient.executeRows(goodsDao.add(formData));
    },taskExecutor).join();
  }

  public String edit(final HttpServletRequest request){
    return CompletableFuture.supplyAsync(()->{
      final PageFormData formData = new PageFormData(request);
      final String p_kid = "kid";
      final String p_contract_name = "contract_name";
      final String p_contract_type = "contract_type";
      final String p_thumbnail = "thumbnail";
      final String p_coupon = "coupon";
      final String p_details = "details";
      final String p_price = "price";
      final String validate = ToolClient.validateField(formData,p_kid,p_contract_name,p_details,p_price,p_coupon);
      if(validate != null) return validate;
      final String len_contract_name = formData.getString(p_contract_name);
      if(len_contract_name != null && len_contract_name.length() > 64){
        return ToolClient.createJsonFail("商品名称字数太多");
      }
      final String len_contract_type = formData.getString(p_contract_type);
      if(len_contract_type != null && len_contract_type.length() > 19){
        return ToolClient.createJsonFail("商品类型字数太多");
      }
      final String len_details = formData.getString(p_details);
      if(len_details != null && len_details.length() > 921600000){
        return ToolClient.createJsonFail("商品描述字数太多");
      }
      final Integer couponValue = formData.getInteger(p_coupon);
      if(couponValue == null){
        return ToolClient.createJsonFail("优惠券数量数据格式有误");
      }
      if(couponValue < 0){
        return ToolClient.createJsonFail("优惠券数量不能小于0");
      }
      formData.put(p_coupon,couponValue);
      final String len_price = formData.getString(p_price);
      if(len_price != null && len_price.length() > 12){
        return ToolClient.createJsonFail("商品价格字数太多");
      }
      final Long v_contract_type = formData.getLong(p_contract_type);
      if(v_contract_type != null){
        formData.put(p_contract_type,v_contract_type);
      }
      final BigDecimal v_price = formData.getBigDecimal(p_price);
      if(v_price == null){
        return ToolClient.createJsonFail("商品价格不是有效的数字");
      }else{
        formData.put(p_price,v_price);
      }
      final HashMap<String,String> v = goodsDao.queryExistById(formData.getLong(p_kid));
      if(v == null){
        return ToolClient.createJsonFail("数据不存在,刷新重试");
      }
      final String baseDir = ToolString.isLinuxOS() ? dir_linux : dir_window;
      final UploadObject uploadObject = ToolClient.uploadFile(request,baseDir,"/goods",false,1,2,null,".jpg",".jpeg",".svg",".png");
      final String errorMsg = uploadObject.getErrorMsg();
      if(errorMsg != null) return ToolClient.createJsonFail(errorMsg);
      final ArrayList<UploadFile> listFiles = uploadObject.getListFiles();
      final boolean b = listFiles != null && !listFiles.isEmpty();
      formData.remove(p_thumbnail);
      if(b){
        final ArrayList<String> lists = new ArrayList<>(1);
        lists.add(p_thumbnail);
        handlerFile(formData,listFiles,lists);//适用于json类型(单文件上传)
      }
      formData.put(p_kid,formData.getLong(p_kid));
      final int rows = goodsDao.edit(formData);
      if(rows > 0 && b){
        for(int y = listFiles.size() - 1; y >= 0; y--){
          final String fileName = listFiles.get(y).getName();
          for(final String key : v.keySet()){
            if(key.equals(fileName)){
              asyncService.delFileJsonObject(v.get(key));//删除单文件字段的文件
              break;
            }
          }
        }
      }
      return ToolClient.executeRows(rows);
    },taskExecutor).join();
  }

  //适用于添加或编辑的单文件上传
  public void handlerFile(final PageFormData formData,final ArrayList<UploadFile> listFiles,final ArrayList<String> lists){
    listFiles.forEach(uploadFile -> {
      final JSONObject json = new JSONObject(3);
      json.put("fullPath",uploadFile.getFullPath());
      json.put("urlFile",uploadFile.getUrlFile());
      json.put("fileSize",uploadFile.getFileSize());
      json.put("originalName",uploadFile.getOriginalName());
      final String name = uploadFile.getName();
      for(int i = lists.size() - 1; i >= 0; i--){
        final String value = lists.get(i);
        if(name.equals(value)){
          formData.put(name,json.toJSONString());
          break;
        }
      }
    });
  }

  public String queryById(final Long kid){
    return CompletableFuture.supplyAsync(()->{
      if(kid == null){
        return ToolClient.jsonValidateField();
      }
      return ToolClient.queryJson(goodsDao.queryById(kid));
    },taskExecutor).join();
  }

  //编辑时的文件删除可参考此方法
  public String delById(final Long kid){
    //若用到ThreadLocal的数据可在此组装
    return CompletableFuture.supplyAsync(()->{
      if(kid == null){
        return ToolClient.jsonValidateField();
      }
      final HashMap<String,String> map = goodsDao.queryExistById(kid);
      if(map == null){
        return ToolClient.createJsonFail("数据不存在,刷新重试");
      }
      return ToolClient.executeRows(goodsDao.delById(kid),"操作成功","删除失败,刷新重试");
    },taskExecutor).join();
  }

  public String delByKeys(final String ids){
    return CompletableFuture.supplyAsync(()->{
      if(ids == null || ids.length() <= 0){
        return ToolClient.jsonValidateField();
      }
      final long[] list = ToolString.keysToArarry(ids);
      if(list == null){
        return ToolClient.createJsonFail("请选择要删除的数据");
      }
      final List<HashMap<String,String>> files = goodsDao.queryFiles(list);
      if(files.isEmpty()){
        return ToolClient.createJsonFail("数据不存在,刷新重试");
      }
      return ToolClient.executeRows(goodsDao.delByKeys(list),"操作成功","数据不存在,刷新重试");
    },taskExecutor).join();
  }

  public String listData(final PageFormData formData){
    return CompletableFuture.supplyAsync(()->{
      try{
        if(ToolClient.dataTableMysql(formData) == null) return ToolClient.jsonValidateField();
        final CompletableFuture<List<HashMap<String,Object>>> listData = CompletableFuture.supplyAsync(() -> goodsDao.getListData(formData),taskExecutor);
        final CompletableFuture<Integer> listTotal = CompletableFuture.supplyAsync(() -> goodsDao.getListTotal(formData),taskExecutor);
        return ToolClient.dataTableOK(listData.join(),listTotal.join());
      } catch (final Exception ignored){
        return ToolClient.dataTableException();
      }
    },taskExecutor).join();
  }

  //获取表goods的字段contract_type的下拉框列动态值选项的数据
  public String getContract_type(){
    return CompletableFuture.supplyAsync(()->ToolClient.queryJson(goodsDao.getContract_type()),taskExecutor).join();
  }

  public String editIntegral(final HttpServletRequest request){
    return CompletableFuture.supplyAsync(()->{
      final PageFormData formData = new PageFormData(request);
      final String p_level_value1 = "value1";
      final String p_level_value2 = "value2";
      final String p_level_value3 = "value3";
      final String p_level_value4 = "value4";
      final String p_level_value5 = "value5";//推荐人积分,仅有积分,不含securitie5

      final String p_securitie1 = "securitie1";
      final String p_securitie2 = "securitie2";
      final String p_securitie3 = "securitie3";
      final String p_securitie4 = "securitie4";
      final String p_securitie5 = "securitie5";

      final ArrayList<HashMap<String,Object>> list = new ArrayList<>(5);
      handlerValues(list,1,formData,p_level_value1,p_securitie1);
      handlerValues(list,2,formData,p_level_value2,p_securitie2);
      handlerValues(list,3,formData,p_level_value3,p_securitie3);
      handlerValues(list,4,formData,p_level_value4,p_securitie4);
      handlerValues(list,5,formData,p_level_value5,p_securitie5);

      return ToolClient.executeRows(goodsDao.editIntegral(list));
    },taskExecutor).join();
  }

  private void handlerValues(final ArrayList<HashMap<String,Object>> list,final int value,final PageFormData formData,final String p_level_value,final String p_discounts){
    final HashMap<String,Object> map = new HashMap<>(4);
    final Long kid = formData.getLong("kid");
    map.put("goods_id",kid);
    map.put("level_value",value);
    final Object score = formData.get(p_level_value);
    map.put("score",score == null ? 0 : score);
    final Object discount = formData.get(p_discounts);
    map.put("discounts",discount == null ? 0 : discount);
    list.add(map);
  }
}